package com.nuoniu.sibanyun.service.crm.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.entity.SysUser;
import com.nuoniu.sibanyun.entity.SysUserRole;
import com.nuoniu.sibanyun.entity.bo.ProcessSimpleBo;
import com.nuoniu.sibanyun.entity.crm.Approval;
import com.nuoniu.sibanyun.entity.crm.ApprovalProcess;
import com.nuoniu.sibanyun.entity.crm.CrmCustomer;
import com.nuoniu.sibanyun.entity.crm.WithdrawalRecord;
import com.nuoniu.sibanyun.mapper.SysUserMapper;
import com.nuoniu.sibanyun.mapper.SysUserRoleMapper;
import com.nuoniu.sibanyun.mapper.crm.ApprovalMapper;
import com.nuoniu.sibanyun.mapper.crm.ApprovalProcessMapper;
import com.nuoniu.sibanyun.mapper.crm.CrmCustomerMapper;
import com.nuoniu.sibanyun.mapper.crm.WithdrawalRecordMapper;
import com.nuoniu.sibanyun.service.crm.IApprovalService;
import com.nuoniu.sibanyun.service.crm.ICrmCustomerService;
import com.nuoniu.sibanyun.service.crm.IWithdrawalRecordService;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <p>
 * 审批记录 服务实现类
 * </p>
 *
 * @author baiqiang
 * @since 2020-06-20
 */
@Log4j2
@Service
public class ApprovalServiceImpl extends ServiceImpl<ApprovalMapper, Approval> implements IApprovalService {

    @Autowired
    private SysUserRoleMapper roleMapper;
    @Autowired
    private ApprovalMapper approvalMapper;
    @Autowired
    @Lazy
    private ICrmCustomerService crmCustomerService;
    @Autowired
    private ApprovalProcessMapper processMapper;
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private IWithdrawalRecordService withdrawalRecordService;
    @Autowired
    private WithdrawalRecordMapper withdrawalRecordMapper;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void approvalAll(String ids, Integer type, String content) {
        long timeMillis = System.currentTimeMillis();
        List<Approval> approvalList = new ArrayList<>();
        List<CrmCustomer> updateCustomerList = new ArrayList<>();
        List<WithdrawalRecord> updateWithdrawalRecordList = new ArrayList<>();
        List<ProcessSimpleBo> processSimpleBos = new ArrayList<>();
        List<Approval> closeApprovalList = new ArrayList<>();
        String[] idArr = ids.split(",");
        for (String id : idArr) {
            Approval approval = getById(id);
            if (approval.getApprovalResult() != 0) {
                continue;
            }
            approval.setApprovalOpinion(content);
            approval.setApprovalResult(type);
            approval.setApprovalDate(new Date());

            Approval updateApproval = new Approval();
            updateApproval.setId(approval.getId());
            updateApproval.setApprovalOpinion(content);
            updateApproval.setApprovalResult(type);
            updateApproval.setApprovalDate(new Date());
            approvalList.add(updateApproval);

            //保存审批记录
            saveApproval(approval,updateCustomerList,updateWithdrawalRecordList,processSimpleBos,closeApprovalList);
        }
        long selectTime = System.currentTimeMillis();
        log.debug("批量传入{}个记录，成功审批{}个审批记录，查询组装数据 耗时{}毫秒",idArr.length, approvalList.size(),selectTime - timeMillis);
        if(approvalList.size() > 0){
            updateBatchById(approvalList,100);
        }
        if(updateCustomerList.size() > 0){
            crmCustomerService.updateBatchById(updateCustomerList);
        }
        if(updateWithdrawalRecordList.size() > 0){
            withdrawalRecordService.updateBatchById(updateWithdrawalRecordList);
        }
        if(processSimpleBos.size() > 0){
            batchStartProcess(processSimpleBos);
        }
        if(closeApprovalList.size() > 0){
            updateBatchById(closeApprovalList);
        }
        long lastTime = System.currentTimeMillis();
        log.debug("批量传入{}个记录，成功审批{}个审批记录，批量保存耗时 耗时{}毫秒，总耗时{}毫秒",idArr.length, approvalList.size(),lastTime - selectTime,lastTime - timeMillis);
    }

    @Override
    @Transactional
    public void startProcess(Long approvalProcessId, Long sourceId, String content, String approvalUserId, Integer processType, Integer approvalMode, int size) {
        UserInfo userInfo = UserThreadLocal.get();
        String[] userIds = approvalUserId.split(",");
        for (String userId : userIds) {
            SysUser user = userMapper.selectById(userId);
            Approval approval = new Approval();
            if(processType == 5) {
                approval.setCompanyId(1);
                approval.setCompanyName("诺牛科技");
            }else {
                approval.setCompanyId(userInfo.getCompanyId());
                approval.setCompanyName(userInfo.getCompanyName());
            }
            approval.setApprovalUserId(Integer.parseInt(userId));
            approval.setApprovalUserName(user.getRealName());
            approval.setSourceId(sourceId);
            approval.setProcessId(approvalProcessId);
            approval.setProcessName(content);
            approval.setApprovalMode(approvalMode);
            approval.setApprovalSize(size);
            approval.setApprovalType(processType);
            approval.setApprovalResult(0);
            approval.setCreateUserId(userInfo.getUserId());
            approval.setCreateUserName(userInfo.getRealName());
            save(approval);
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void batchStartProcess(List<ProcessSimpleBo> processSimpleBos) {
        UserInfo userInfo = UserThreadLocal.get();
        List<Approval> approvalList = new ArrayList<>();
        for (ProcessSimpleBo processSimpleBo :processSimpleBos ) {
            String[] userIds = processSimpleBo.getApprovalUserId().split(",");
            for (String userId : userIds) {
                SysUser user = userMapper.selectById(userId);
                Approval approval = new Approval();
                if(processSimpleBo.getProcessType() == 5) {
                    approval.setCompanyId(1);
                    approval.setCompanyName("诺牛科技");
                }else {
                    approval.setCompanyId(userInfo.getCompanyId());
                    approval.setCompanyName(userInfo.getCompanyName());
                }
                approval.setApprovalUserId(Integer.parseInt(userId));
                approval.setApprovalUserName(user.getRealName());
                approval.setSourceId(processSimpleBo.getSourceId());
                approval.setProcessId(processSimpleBo.getApprovalProcessId());
                approval.setProcessName(processSimpleBo.getContent());
                approval.setApprovalMode(processSimpleBo.getApprovalMode());
                approval.setApprovalSize(processSimpleBo.getSize());
                approval.setApprovalType(processSimpleBo.getProcessType());
                approval.setApprovalResult(0);
                approval.setCreateUserId(userInfo.getUserId());
                approval.setCreateUserName(userInfo.getRealName());
                approvalList.add(approval);
//                if(approvalList.size() == 100){
//                    saveBatch(approvalList);
//                    approvalList = new ArrayList<>();
//                }
            }
        }
       if(approvalList.size() > 0){
           saveBatch(approvalList);
       }
    }


    @Override
    public Page<Approval> pageApproval(Page pages, Approval approval) {
        UserInfo userInfo = UserThreadLocal.get();
        SysUserRole userRole = roleMapper.getUserAdminRole(userInfo.getUserId(), 9);
        QueryWrapper<Approval> queryWrapper = new QueryWrapper<>(approval);
        queryWrapper.eq("company_id", userInfo.getCompanyId());
        queryWrapper.eq("status", 0);
        if(userRole == null) {
            queryWrapper.eq("approval_user_id", userInfo.getUserId());
        }
        queryWrapper.orderByDesc("create_date");
        return page(pages, queryWrapper);
    }

    @Override
    public void saveApproval(Approval approval,List<CrmCustomer> updateCustomerList,List<WithdrawalRecord> updateWithdrawalRecordList,List<ProcessSimpleBo> processSimpleBos, List<Approval> closeApprovalList) {
        UserInfo userInfo = UserThreadLocal.get();
        Integer next = completeProcess(approval,closeApprovalList);
        if (0 == next) { //通过
            if(approval.getApprovalType() == 1) { //客户审批
                CrmCustomer customer = crmCustomerService.getById(approval.getSourceId());
                CrmCustomer updateCrmCustomer = new CrmCustomer();
                updateCrmCustomer.setId(customer.getId());
                updateCrmCustomer.setCrmType(1);
                updateCrmCustomer.setApprovalType(1);
                updateCustomerList.add(updateCrmCustomer);
//                crmCustomerMapper.updateById(customer);
                //msgInnerService.sendMsg("客户审核消息", "你的" + company.getCompanyName() + "客户审批已通过", UserUtils.get(company.getCollarUser().getUserCode()));
            }
            if(approval.getApprovalType() == 5) { //提现审批
                WithdrawalRecord record = new WithdrawalRecord();
                record.setId(approval.getSourceId());
                record.setStatus(4);
                updateWithdrawalRecordList.add(record);
                withdrawalRecordMapper.updateById(record);
            }
        } else if (-1 == next) { //驳回
            if (approval.getApprovalType() == 1) { //客户审批:不通过则返回公海客户
                CrmCustomer customer = crmCustomerService.getById(approval.getSourceId());
                CrmCustomer updateCrmCustomer = new CrmCustomer();
                updateCrmCustomer.setId(customer.getId());
                updateCrmCustomer.setCrmType(0);
                updateCrmCustomer.setApprovalType(0);
                updateCustomerList.add(updateCrmCustomer);
//                crmCustomerMapper.updateById(customer);
                //msgInnerService.sendMsg("客户审核消息", "你的" + company.getCompanyName() + " 客户审批未通过", UserUtils.get(company.getCollarUser().getUserCode()));
            }
            if(approval.getApprovalType() == 5) { //提现审核
                WithdrawalRecord record = new WithdrawalRecord();
                record.setId(approval.getSourceId());
                record.setStatus(3);
                updateWithdrawalRecordList.add(record);
//                withdrawalRecordMapper.updateById(record);
            }
        } else if (-2 == next) {
            // 或签单个不通过
        } else {
            List<ApprovalProcess> list = processMapper.getProcessByType(1, userInfo.getCompanyId());
            if (list.size() == 0) {
                throw new NuoNiuException("未创建客户流程");
            }
            ApprovalProcess approvalProcess = list.get(list.size() - next);// 下一步审批步骤

            ProcessSimpleBo processSimpleBo = new ProcessSimpleBo();
            processSimpleBo.setApprovalProcessId(approval.getId());
            processSimpleBo.setSourceId(approval.getSourceId());
            processSimpleBo.setContent(approval.getProcessName());
            processSimpleBo.setApprovalUserId( approvalProcess.getApprovalUserId());
            processSimpleBo.setProcessType( approvalProcess.getProcessType());
            processSimpleBo.setApprovalMode(approvalProcess.getApprovalMode());
            processSimpleBo.setSize(list.size());
            processSimpleBos.add(processSimpleBo);

//            startProcess(approval.getProcessId(), approval.getSourceId(), approval.getProcessName(), approvalProcess.getApprovalUserId(), approvalProcess.getApprovalType(), approvalProcess.getApprovalMode(), next);
        }

    }

    @Transactional
    public Integer completeProcess(Approval approval, List<Approval> closeApprovalList) {
        Integer next = 0;// 0代表结束
//        approval.setApprovalDate(new Date());
//        updateById(approval);
        if (approval.getApprovalMode() == 2) {
            if (1 == approval.getApprovalResult()) {
                // 有一个通过则关闭其他

                Approval hrApproval = new Approval();
                hrApproval.setProcessId(approval.getProcessId());
                hrApproval.setSourceId(approval.getSourceId());
                hrApproval.setApprovalSize(approval.getApprovalSize());
                hrApproval.setApprovalResult(0);
                hrApproval.setStatus("0");
                QueryWrapper<Approval> queryWrapper = new QueryWrapper<>(hrApproval);
                queryWrapper.select("id");
                List<Approval> approvals = list(queryWrapper);
//                List<Approval> approvals = approvalMapper.getList(hrApproval);
                for (Approval app : approvals) {
                    app.setApprovalResult(3);
//                    updateById(app);
                }
                closeApprovalList.addAll(approvals);
                next = approval.getApprovalSize() - 1;
            } else {
                // 如果全部不通过则返回-1
                Approval hrApproval = new Approval();
                hrApproval.setProcessId(approval.getProcessId());
                hrApproval.setSourceId(approval.getSourceId());
                hrApproval.setApprovalSize(approval.getApprovalSize());
                List<Approval> list1 = approvalMapper.getList(hrApproval);
                hrApproval.setApprovalResult(2);
                List<Approval> list2 = approvalMapper.getList(hrApproval);
                if (list1.size() == list2.size()) {
                    next = -1;
                } else {
                    next = -2;
                }
            }
        } else {
            // 会签 有一个不通过则返回-1
            if (approval.getApprovalResult() == 2) {
                next = -1;

                Approval hrApproval = new Approval();
                hrApproval.setSourceId(approval.getSourceId());
                hrApproval.setApprovalSize(approval.getApprovalSize());
                hrApproval.setApprovalResult(0);
                hrApproval.setStatus("0");
                QueryWrapper<Approval> queryWrapper = new QueryWrapper<>(hrApproval);
                queryWrapper.select("id");
                List<Approval> approvals = list(queryWrapper);
//                List<Approval> list = approvalMapper.getList(hrApproval);
                for (Approval app : approvals) {
                    app.setApprovalResult(3);
//                    updateById(app);
                }
                closeApprovalList.addAll(approvals);
            } else {
                Approval hrApproval = new Approval();
                hrApproval.setSourceId(approval.getSourceId());
                hrApproval.setApprovalSize(approval.getApprovalSize());
                hrApproval.setApprovalResult(0);
                List<Approval> list2 = approvalMapper.getList(hrApproval);
                if (list2.size() == 0) {
                    next = approval.getApprovalSize().intValue() - 1 ;
                } else {
                    next = -2;
                }
            }
        }
        return next;
    }
}
